{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e9dbd1c6-4248-4f45-8cb8-2cc31330ff5a",
   "metadata": {},
   "source": [
    "Chapter 10\n",
    "\n",
    "# 使用scikit-learn完成一元多项式回归\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd0b5004-f7c8-4e29-94ac-54b02e27075e",
   "metadata": {},
   "source": [
    "这段代码完整地实现了**一元八次多项式回归**的训练、预测与可视化过程，核心思想是在一维自变量 $x$ 上构造高阶多项式特征，并使用线性回归进行拟合。本质上，它利用了**特征升维 + 线性模型 = 非线性拟合能力增强**这一思路。我们从数学角度逐步解释每部分在做什么。\n",
    "\n",
    "---\n",
    "\n",
    "首先，代码读取了一组二维数据点，并将其分成输入 $x$ 和输出 $y$。形式如下：\n",
    "\n",
    "$$\n",
    "x = \\begin{bmatrix} 1 \\\\ 2 \\\\ 4 \\\\ 5 \\\\ 6 \\\\ 7 \\\\ 8 \\\\ 9 \\end{bmatrix}, \\quad\n",
    "y = \\begin{bmatrix} 1 \\\\ 7 \\\\ 8 \\\\ 6 \\\\ 5 \\\\ 2 \\\\ 2 \\\\ 4 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### 一、特征构造（Polynomial Features）\n",
    "\n",
    "设定多项式阶数为 $8$，通过 `PolynomialFeatures(degree=8)` 构造一个新的设计矩阵 $X_{\\text{poly}}$，其每一行包含如下内容：\n",
    "\n",
    "$$\n",
    "X_{\\text{poly}} = \n",
    "\\begin{bmatrix}\n",
    "1 & x & x^2 & x^3 & \\dots & x^8\n",
    "\\end{bmatrix}\n",
    "$$\n",
    "\n",
    "例如，对于 $x = 2$，构造出的特征向量为：\n",
    "\n",
    "$$\n",
    "[1, 2, 4, 8, 16, 32, 64, 128, 256]\n",
    "$$\n",
    "\n",
    "因此，对于每个样本点，特征维度从原来的 $1$ 升到了 $9$。这一步的核心是将原始一维变量 $x$ 投射到高维的特征空间中，使模型具有拟合复杂曲线的能力。\n",
    "\n",
    "---\n",
    "\n",
    "### 二、模型训练（最小二乘线性回归）\n",
    "\n",
    "使用 `LinearRegression()` 对构造出的特征进行拟合，目标是最小化平方误差，即求解以下最优化问题：\n",
    "\n",
    "$$\n",
    "\\min_{\\mathbf{b}} \\| X_{\\text{poly}} \\cdot \\mathbf{b} - y \\|^2\n",
    "$$\n",
    "\n",
    "其解析解为正规方程形式：\n",
    "\n",
    "$$\n",
    "\\mathbf{b} = (X^\\top X)^{-1} X^\\top y\n",
    "$$\n",
    "\n",
    "这里 $\\mathbf{b}$ 是一个 $9 \\times 1$ 的参数向量：\n",
    "\n",
    "$$\n",
    "\\mathbf{b} = \n",
    "\\begin{bmatrix}\n",
    "b_0 \\\\ b_1 \\\\ b_2 \\\\ \\dots \\\\ b_8\n",
    "\\end{bmatrix}\n",
    "$$\n",
    "\n",
    "回归预测值为：\n",
    "\n",
    "$$\n",
    "\\hat{y} = X_{\\text{poly}} \\cdot \\mathbf{b}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### 三、预测与可视化\n",
    "\n",
    "为了绘制回归曲线，代码在区间 $[0,10]$ 上生成了101个等距点，并用训练好的模型对这些点进行预测：\n",
    "\n",
    "$$\n",
    "\\hat{y}_{\\text{curve}} = \\text{poly\\_reg.predict}(X_{\\text{array}})\n",
    "$$\n",
    "\n",
    "其中 $X_{\\text{array}}$ 是新的输入点构造成的多项式特征。\n",
    "\n",
    "最终图像中：\n",
    "\n",
    "- 蓝色叉号为原始数据点 $(x_i, y_i)$；\n",
    "- 红色叉号为预测点 $(x_i, \\hat{y}_i)$；\n",
    "- 黄色半透明线段连接真实值与预测值，表示残差；\n",
    "- 红色曲线为八次多项式拟合出的函数图像。\n",
    "\n",
    "---\n",
    "\n",
    "### 四、模型表达式（回归公式）\n",
    "\n",
    "回归系数保存在 `coef` 中，常数项为 `intercept`，它们共同构成了最终回归模型的表达式：\n",
    "\n",
    "$$\n",
    "\\hat{y} = b_0 + b_1 x + b_2 x^2 + \\cdots + b_8 x^8\n",
    "$$\n",
    "\n",
    "代码将其格式化为 LaTeX 形式，并打印如下公式：\n",
    "\n",
    "```python\n",
    "y = 0.518 + 3.733x - 3.695x^2 + 1.082x^3 - 0.123x^4 + ...\n",
    "```\n",
    "\n",
    "注意：由于模型是高阶多项式，它的表达能力极强，可以拟合各种非线性趋势，但也容易出现“过拟合”，即模型过度追踪训练数据，导致泛化能力下降。\n",
    "\n",
    "---\n",
    "\n",
    "### 总结\n",
    "\n",
    "从数学视角看，这段代码实现了将一元非线性问题通过高阶多项式特征转化为线性模型，并通过最小二乘法拟合参数，从而完成对数据的建模。高阶多项式提供了强大的拟合能力，图像展示也很好地体现了拟合精度与模型复杂度之间的平衡关系。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e7a84f8-9591-46d9-acc8-8dd6d8f28859",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "27485785-fcc0-43fa-923c-876809ecf7db",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "from sklearn.linear_model import LinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b7a1fd17-1e39-4489-9dd2-c76d59deb59f",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.array([[1, 1],\n",
    "                 [2, 7],\n",
    "                 [4, 8],\n",
    "                 [5, 6],\n",
    "                 [6, 5],\n",
    "                 [7, 2],\n",
    "                 [8, 2],\n",
    "                 [9, 4]])\n",
    "x = data[:,[0]]\n",
    "y = data[:,[1]]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a3aa749-f9b1-48ce-9726-2281eb27e8fe",
   "metadata": {},
   "source": [
    "## 回归模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "40ff158c-f782-4837-b3d0-59f5b40bf780",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_array = np.linspace(0,10,101).reshape(-1,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "54867c9c-0d4b-4966-b2dc-461a6b1705de",
   "metadata": {},
   "outputs": [],
   "source": [
    "degree_idx = 8\n",
    "poly = PolynomialFeatures(degree = degree_idx)\n",
    "X_poly = poly.fit_transform(x.reshape(-1, 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "82fc7eef-5cca-4f03-8841-4d4c0010260c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练线性回归模型\n",
    "poly_reg = LinearRegression()\n",
    "poly_reg.fit(X_poly, y)\n",
    "y_poly_pred = poly_reg.predict(X_poly)\n",
    "data_ = np.column_stack([x,y_poly_pred])\n",
    "\n",
    "y_array_pred = poly_reg.predict(\n",
    "                   poly.fit_transform(x_array))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f351a793-2478-4df2-90d1-91f7a2b152a8",
   "metadata": {},
   "source": [
    "## 可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "093ecf77-03c8-4168-9391-ae2896eb1a45",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.0, 10.0)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(5,5))\n",
    "\n",
    "# 绘制散点图\n",
    "ax.scatter(x, y, marker = 'x', color = 'b')\n",
    "ax.scatter(x, y_poly_pred, marker = 'x', color='r')\n",
    "\n",
    "ax.plot(([i for (i,j) in data_], [i for (i,j) in data]),\n",
    "        ([j for (i,j) in data_], [j for (i,j) in data]),\n",
    "         c='#FFC000', alpha = 0.5)\n",
    "\n",
    "ax.plot(x_array, y_array_pred, color='r')\n",
    "ax.set_title('Degree = %d' % degree_idx)\n",
    "\n",
    "# 提取参数\n",
    "coef = poly_reg.coef_\n",
    "intercept = poly_reg.intercept_\n",
    "# 回归解析式\n",
    "\n",
    "ax.set_aspect('equal', adjustable='box')\n",
    "ax.set_xticks(np.arange(11))\n",
    "ax.set_yticks(np.arange(11))\n",
    "ax.set_xlim(0,10)\n",
    "ax.grid(True, c = '0.8')\n",
    "ax.set_ylim(0,10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "15811bd9-2242-4425-ae16-b1bace1456fc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "$y = 7.123 -11.430x^1 -2.828x^2 + 15.342x^3 -9.463x^4 + 2.599x^5 -0.370x^6 + 0.027x^7 -0.001x^8$\n"
     ]
    }
   ],
   "source": [
    "equation = '$y = {:.3f}'.format(intercept[0])\n",
    "for j in range(1, len(coef[0])):\n",
    "    equation += ' + {:.3f}x^{}'.format(coef[0][j], j)\n",
    "equation += '$'\n",
    "equation = equation.replace(\"+ -\", \"-\")\n",
    "print(equation)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06de12c2-2ca1-4e50-ad57-74190d7f1655",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
